
`include "defines.v"

//----------------------------------------------------------------
//Module Name : clint_reg.v
//Description of module:
// 
//----------------------------------------------------------------
//Designer:	Tang Pengyu
//Date: 2021/09/22	  
//----------------------------------------------------------------

module	clint_reg(
	input	clk,
	input	rst,
	input	load_clint_en,
	input	clint_w_ena,
	input	[63:0]	load_store_addr,
	input	[63:0]	store_clint_data,
	
	output	[63:0]	load_clint_data,
	output	time_overstep
	
	
);

reg		[63:0]	mtime;
wire	mtime_sel;
wire	mtime_w_ena;
wire	mtime_r_ena;
assign	mtime_sel = (load_store_addr == 64'h0000_0000_0200_bff8);
assign	mtime_w_ena = mtime_sel & clint_w_ena;
assign	mtime_r_ena = mtime_sel & load_clint_en;
always @(posedge clk or posedge rst)	begin
	if(rst)
		mtime <= 64'd0;
	else if(mtime_w_ena)
		mtime <= store_clint_data;
	else	
		mtime <= mtime + 1'b1;

end

reg		[63:0]	mtimecmp;
wire	mtimecmp_sel;
wire	mtimecmp_w_ena;
wire	mtimecmp_r_ena;
assign	mtimecmp_sel = (load_store_addr == 64'h0000_0000_0200_4000);
assign	mtimecmp_w_ena = mtimecmp_sel & clint_w_ena;
assign	mtimecmp_r_ena = mtimecmp_sel & load_clint_en;
always @(posedge clk or posedge rst)	begin
	if(rst)
		mtimecmp <= 64'd0;
	else if(mtimecmp_w_ena)
		mtimecmp <= store_clint_data;
//		mtimecmp <= mtimecmp + 64'h0000_0000_000F_F000;

end

assign	load_clint_data = ({64{mtime_r_ena}} & mtime) | 
						({64{mtimecmp_r_ena}} & mtimecmp);
						
assign	time_overstep = ((mtime == mtimecmp) | (mtime > mtimecmp)) ? 1'b1 : 1'b0;


endmodule
